/*
 Create a TCP socket
 */

#include "communication.h"

int clientIndex = 0;


WSADATA wsa;
SOCKET testSocket;

/**
 * Create a temporary SOCKET object called ClientSocket for
 * accepting connections from clients.
 */
SOCKET ClientSocket = INVALID_SOCKET;

SOCKET ListenSocket = INVALID_SOCKET;

char sendBuffer[2000];

#define DEFAULT_BUFLEN 512
struct addrinfo *result = NULL, *ptr = NULL, hints;
char recvbuf[DEFAULT_BUFLEN];
int iResult, iSendResult;
int recvbuflen = DEFAULT_BUFLEN;

int initSocket() {
	int iResult;

	WSADATA wsaData;

	iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (iResult != 0) {
		printf("WSAStartup failed: %d\n", iResult);
		return 1;
	}

	ZeroMemory(&hints, sizeof (hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE;

	// Resolve the local address and port to be used by the server
	iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
	if (iResult != 0) {
		printf("getaddrinfo failed: %d\n", iResult);
		WSACleanup();
		return 1;
	}

	// Create a SOCKET for the server to listen for client connections
	ListenSocket = socket(result->ai_family, result->ai_socktype,
			result->ai_protocol);

	// Check for errors to ensure that the socket is a valid socket.
	if (ListenSocket == INVALID_SOCKET) {
		printf("Error at socket(): %d\n", WSAGetLastError());
		freeaddrinfo(result);
		WSACleanup();
		return 1;
	}

	puts("Setting up TCP listening socket...");
	fflush(stdout);

	// Setup the TCP listening socket
	iResult = bind(ListenSocket, result->ai_addr, (int) result->ai_addrlen);
	if (iResult == SOCKET_ERROR) {
		printf("bind failed with error: %d\n", WSAGetLastError());
		freeaddrinfo(result);
		closesocket(ListenSocket);
		WSACleanup();
		return 1;
	}

	// Once the bind function is called, the address information returned
	// by the getaddrinfo function is no longer needed.
	freeaddrinfo(result);

	puts("Putting socket in listen state...");
	fflush(stdout);

	// Call the listen function, passing as parameters the created
	// socket and a value for the backlog, maximum length of the
	// queue of pending connections to accept.
	if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
		printf("Listen failed with error: %d\n", WSAGetLastError());
		closesocket(ListenSocket);
		WSACleanup();
		return 1;
	}
	return 0;
}

/**
 * Waits for a client to connect and returns the client SOCKET.
 */
SOCKET waitForConnection() {
	// Accept a client socket
	ClientSocket = accept(ListenSocket, NULL, NULL );
	if (ClientSocket == INVALID_SOCKET) {
		printf("accept failed: %d\n", WSAGetLastError());
	}
	return ClientSocket;
}

int sendData(char data[], int size) {
	iSendResult = send(ClientSocket, sendBuffer, size, 0);
	if (iSendResult == SOCKET_ERROR) {
		printf("send failed: %d\n", WSAGetLastError());
		closesocket(ClientSocket);
		WSACleanup();
		return 1;
	}
}

int waitForData(SOCKET clientSocket, char receiveBuffer[], int bufferLength) {
	iResult = recv(clientSocket, receiveBuffer, bufferLength, 0);
	if (iResult > 0) {
		printf("Bytes received: %d\n", iResult);
		return iResult;
	} else if (iResult == 0) {
		printf("Connection closing...\n");
		return 0;
	} else {
		printf("Receive failed: %d\n", WSAGetLastError());
		closesocket(clientSocket);
		return 1;
	}
}
